Làm chủ Phát triển Hướng Kiểm thử (TDD) trong JavaScript. Hướng dẫn toàn diện này bao gồm chu trình Đỏ-Xanh-Tái cấu trúc, triển khai thực tế với Jest và các phương pháp hay nhất cho phát triển hiện đại.
Phát triển Hướng Kiểm thử trong JavaScript: Hướng dẫn Toàn diện cho Lập trình viên Toàn cầu
Hãy tưởng tượng kịch bản này: bạn được giao nhiệm vụ sửa đổi một đoạn mã quan trọng trong một hệ thống lớn, cũ kỹ. Bạn cảm thấy một nỗi sợ hãi. Liệu thay đổi của bạn có làm hỏng thứ gì khác không? Làm sao bạn có thể chắc chắn hệ thống vẫn hoạt động như dự kiến? Nỗi sợ thay đổi này là một căn bệnh phổ biến trong phát triển phần mềm, thường dẫn đến tiến độ chậm và các ứng dụng dễ vỡ. Nhưng sẽ thế nào nếu có một cách để xây dựng phần mềm một cách tự tin, tạo ra một mạng lưới an toàn giúp phát hiện lỗi trước khi chúng đến tay người dùng? Đây chính là lời hứa của Phát triển Hướng Kiểm thử (Test-Driven Development - TDD).
TDD không chỉ đơn thuần là một kỹ thuật kiểm thử; đó là một phương pháp tiếp cận có kỷ luật đối với thiết kế và phát triển phần mềm. Nó đảo ngược mô hình truyền thống "viết mã, sau đó kiểm thử". Với TDD, bạn viết một bài kiểm thử bị lỗi trước khi bạn viết mã sản phẩm để làm cho nó vượt qua. Sự đảo ngược đơn giản này có ý nghĩa sâu sắc đối với chất lượng mã, thiết kế và khả năng bảo trì. Hướng dẫn này sẽ cung cấp một cái nhìn toàn diện, thực tế về việc triển khai TDD trong JavaScript, được thiết kế cho đối tượng lập trình viên chuyên nghiệp trên toàn cầu.
Phát triển Hướng Kiểm thử (TDD) là gì?
Về cốt lõi, Phát triển Hướng Kiểm thử là một quy trình phát triển dựa trên sự lặp lại của một chu kỳ phát triển rất ngắn. Thay vì viết các tính năng rồi mới kiểm thử chúng, TDD nhấn mạnh rằng bài kiểm thử phải được viết trước. Bài kiểm thử này chắc chắn sẽ thất bại vì tính năng đó chưa tồn tại. Công việc của lập trình viên sau đó là viết đoạn mã đơn giản nhất có thể để làm cho bài kiểm thử cụ thể đó vượt qua. Một khi nó vượt qua, mã sẽ được dọn dẹp và cải thiện. Vòng lặp cơ bản này được gọi là chu kỳ "Đỏ-Xanh-Tái cấu trúc".
Nhịp điệu của TDD: Đỏ-Xanh-Tái cấu trúc
Chu kỳ ba bước này là nhịp đập của TDD. Việc hiểu và thực hành nhịp điệu này là nền tảng để làm chủ kỹ thuật.
- 🔴 Đỏ — Viết một bài kiểm thử thất bại: Bạn bắt đầu bằng cách viết một bài kiểm thử tự động cho một phần chức năng mới. Bài kiểm thử này nên định nghĩa những gì bạn muốn mã thực hiện. Vì bạn chưa viết bất kỳ mã triển khai nào, bài kiểm thử này được đảm bảo sẽ thất bại. Một bài kiểm thử thất bại không phải là vấn đề; đó là sự tiến bộ. Nó chứng minh rằng bài kiểm thử đang hoạt động chính xác (nó có thể thất bại) và đặt ra một mục tiêu rõ ràng, cụ thể cho bước tiếp theo.
- 🟢 Xanh — Viết mã đơn giản nhất để vượt qua: Mục tiêu của bạn bây giờ là duy nhất: làm cho bài kiểm thử vượt qua. Bạn nên viết lượng mã sản phẩm tối thiểu tuyệt đối cần thiết để chuyển bài kiểm thử từ đỏ sang xanh. Điều này có thể cảm thấy phản trực giác; mã có thể không thanh lịch hoặc hiệu quả. Không sao cả. Trọng tâm ở đây hoàn toàn là đáp ứng yêu cầu được định nghĩa bởi bài kiểm thử.
- 🔵 Tái cấu trúc — Cải thiện mã nguồn: Bây giờ bạn đã có một bài kiểm thử vượt qua, bạn có một mạng lưới an toàn. Bạn có thể tự tin dọn dẹp và cải thiện mã của mình mà không sợ làm hỏng chức năng. Đây là nơi bạn giải quyết các "code smell", loại bỏ sự trùng lặp, cải thiện sự rõ ràng và tối ưu hóa hiệu suất. Bạn có thể chạy bộ kiểm thử của mình bất cứ lúc nào trong quá trình tái cấu trúc để đảm bảo bạn không tạo ra bất kỳ lỗi hồi quy nào. Sau khi tái cấu trúc, tất cả các bài kiểm thử vẫn phải có màu xanh.
Một khi chu kỳ hoàn thành cho một phần chức năng nhỏ, bạn lại bắt đầu với một bài kiểm thử thất bại mới cho phần tiếp theo.
Ba Quy luật của TDD
Robert C. Martin (thường được gọi là "Chú Bob"), một nhân vật chủ chốt trong phong trào phần mềm Agile, đã định nghĩa ba quy tắc đơn giản hệ thống hóa kỷ luật TDD:
- Bạn không được viết bất kỳ mã sản phẩm nào trừ khi để làm cho một bài kiểm thử đơn vị thất bại vượt qua.
- Bạn không được viết nhiều hơn một bài kiểm thử đơn vị so với mức đủ để thất bại; và lỗi biên dịch cũng là thất bại.
- Bạn không được viết nhiều mã sản phẩm hơn mức đủ để vượt qua một bài kiểm thử đơn vị đang thất bại.
Tuân theo các quy luật này buộc bạn phải vào chu kỳ Đỏ-Xanh-Tái cấu trúc và đảm bảo rằng 100% mã sản phẩm của bạn được viết để đáp ứng một yêu cầu cụ thể, đã được kiểm thử.
Tại sao bạn nên áp dụng TDD? Lợi ích kinh doanh trên toàn cầu
Trong khi TDD mang lại những lợi ích to lớn cho các nhà phát triển cá nhân, sức mạnh thực sự của nó được hiện thực hóa ở cấp độ nhóm và doanh nghiệp, đặc biệt là trong các môi trường phân tán toàn cầu.
- Tăng sự tự tin và tốc độ: Một bộ kiểm thử toàn diện hoạt động như một mạng lưới an toàn. Điều này cho phép các nhóm thêm tính năng mới hoặc tái cấu trúc các tính năng hiện có một cách tự tin, dẫn đến tốc độ phát triển bền vững cao hơn. Bạn dành ít thời gian hơn cho việc kiểm thử hồi quy thủ công và gỡ lỗi, và nhiều thời gian hơn để cung cấp giá trị.
- Cải thiện thiết kế mã nguồn: Viết kiểm thử trước buộc bạn phải suy nghĩ về cách mã của bạn sẽ được sử dụng. Bạn là người tiêu dùng đầu tiên của API của chính mình. Điều này tự nhiên dẫn đến phần mềm được thiết kế tốt hơn với các mô-đun nhỏ hơn, tập trung hơn và sự tách biệt trách nhiệm rõ ràng hơn.
- Tài liệu sống: Đối với một nhóm toàn cầu làm việc trên các múi giờ và nền văn hóa khác nhau, tài liệu rõ ràng là rất quan trọng. Một bộ kiểm thử được viết tốt là một dạng tài liệu sống, có thể thực thi. Một nhà phát triển mới có thể đọc các bài kiểm thử để hiểu chính xác một đoạn mã phải làm gì và nó hoạt động như thế nào trong các kịch bản khác nhau. Không giống như tài liệu truyền thống, nó không bao giờ có thể trở nên lỗi thời.
- Giảm tổng chi phí sở hữu (TCO): Lỗi được phát hiện sớm trong chu kỳ phát triển sẽ rẻ hơn theo cấp số nhân để sửa chữa so với những lỗi được tìm thấy trong sản phẩm. TDD tạo ra một hệ thống mạnh mẽ, dễ bảo trì và mở rộng theo thời gian, giảm TCO dài hạn của phần mềm.
Thiết lập môi trường TDD JavaScript của bạn
Để bắt đầu với TDD trong JavaScript, bạn cần một vài công cụ. Hệ sinh thái JavaScript hiện đại cung cấp những lựa chọn tuyệt vời.
Các thành phần cốt lõi của một Testing Stack
- Trình chạy kiểm thử: Một chương trình tìm và chạy các bài kiểm thử của bạn. Nó cung cấp cấu trúc (như các khối `describe` và `it`) và báo cáo kết quả. Jest và Mocha là hai lựa chọn phổ biến nhất.
- Thư viện xác nhận: Một công cụ cung cấp các hàm để xác minh rằng mã của bạn hoạt động như mong đợi. Nó cho phép bạn viết các câu lệnh như `expect(result).toBe(true)`. Chai là một thư viện độc lập phổ biến, trong khi Jest bao gồm thư viện xác nhận mạnh mẽ của riêng nó.
- Thư viện Mock: Một công cụ để tạo ra các "bản giả" của các phụ thuộc, như các cuộc gọi API hoặc kết nối cơ sở dữ liệu. Điều này cho phép bạn kiểm thử mã của mình một cách cô lập. Jest có khả năng mocking tích hợp tuyệt vời.
Vì tính đơn giản và tất cả trong một, chúng tôi sẽ sử dụng Jest cho các ví dụ của mình. Đây là một lựa chọn tuyệt vời cho các nhóm đang tìm kiếm một trải nghiệm "không cần cấu hình".
Hướng dẫn cài đặt từng bước với Jest
Hãy thiết lập một dự án mới cho TDD.
1. Khởi tạo dự án của bạn: Mở terminal của bạn và tạo một thư mục dự án mới.
mkdir js-tdd-project
cd js-tdd-project
npm init -y
2. Cài đặt Jest: Thêm Jest vào dự án của bạn như một phụ thuộc phát triển.
npm install --save-dev jest
3. Cấu hình kịch bản kiểm thử: Mở tệp `package.json` của bạn. Tìm phần `"scripts"` và sửa đổi kịch bản `"test"`. Cũng rất nên thêm một kịch bản `"test:watch"`, rất vô giá cho quy trình làm việc TDD.
"scripts": {
"test": "jest",
"test:watch": "jest --watchAll"
}
Cờ `--watchAll` yêu cầu Jest tự động chạy lại các bài kiểm thử bất cứ khi nào một tệp được lưu. Điều này cung cấp phản hồi tức thì, rất hoàn hảo cho chu kỳ Đỏ-Xanh-Tái cấu trúc.
Vậy là xong! Môi trường của bạn đã sẵn sàng. Jest sẽ tự động tìm các tệp kiểm thử có tên là `*.test.js`, `*.spec.js`, hoặc nằm trong thư mục `__tests__`.
TDD trong thực tế: Xây dựng Module CurrencyConverter
Hãy áp dụng chu kỳ TDD vào một vấn đề thực tế, được hiểu trên toàn cầu: chuyển đổi tiền tệ giữa các loại tiền. Chúng ta sẽ xây dựng một module `CurrencyConverter` từng bước một.
Vòng lặp 1: Chuyển đổi đơn giản với tỷ giá cố định
🔴 ĐỎ: Viết kiểm thử thất bại đầu tiên
Yêu cầu đầu tiên của chúng ta là chuyển đổi một số tiền cụ thể từ một loại tiền tệ này sang một loại tiền tệ khác bằng một tỷ giá cố định. Tạo một tệp mới có tên `CurrencyConverter.test.js`.
// CurrencyConverter.test.js
const CurrencyConverter = require('./CurrencyConverter');
describe('CurrencyConverter', () => {
it('nên chuyển đổi chính xác một số tiền từ USD sang EUR', () => {
// Arrange
const amount = 10; // 10 USD
const expected = 9.2; // Giả sử tỷ giá cố định là 1 USD = 0.92 EUR
// Act
const result = CurrencyConverter.convert(amount, 'USD', 'EUR');
// Assert
expect(result).toBe(expected);
});
});
Bây giờ, hãy chạy trình theo dõi kiểm thử từ terminal của bạn:
npm run test:watch
Bài kiểm thử sẽ thất bại một cách ngoạn mục. Jest sẽ báo cáo một cái gì đó như `TypeError: Cannot read properties of undefined (reading 'convert')`. Đây là trạng thái ĐỎ của chúng ta. Bài kiểm thử thất bại vì `CurrencyConverter` không tồn tại.
🟢 XANH: Viết mã đơn giản nhất để vượt qua
Bây giờ, hãy làm cho bài kiểm thử vượt qua. Tạo tệp `CurrencyConverter.js`.
// CurrencyConverter.js
const rates = {
USD: {
EUR: 0.92
}
};
const CurrencyConverter = {
convert(amount, from, to) {
return amount * rates[from][to];
}
};
module.exports = CurrencyConverter;
Ngay khi bạn lưu tệp này, Jest sẽ chạy lại bài kiểm thử, và nó sẽ chuyển sang màu XANH. Chúng ta đã viết lượng mã tối thiểu tuyệt đối để đáp ứng yêu cầu của bài kiểm thử.
🔵 TÁI CẤU TRÚC: Cải thiện mã nguồn
Mã khá đơn giản, nhưng chúng ta đã có thể nghĩ về những cải tiến. Đối tượng `rates` lồng nhau hơi cứng nhắc. Hiện tại, nó đủ sạch. Điều quan trọng nhất là chúng ta có một tính năng hoạt động được bảo vệ bởi một bài kiểm thử. Hãy chuyển sang yêu cầu tiếp theo.
Vòng lặp 2: Xử lý các loại tiền tệ không xác định
🔴 ĐỎ: Viết một bài kiểm thử cho một loại tiền tệ không hợp lệ
Điều gì sẽ xảy ra nếu chúng ta cố gắng chuyển đổi sang một loại tiền tệ mà chúng ta không biết? Nó có lẽ nên ném ra một lỗi. Hãy định nghĩa hành vi này trong một bài kiểm thử mới trong `CurrencyConverter.test.js`.
// Trong CurrencyConverter.test.js, bên trong khối describe
it('nên ném ra lỗi đối với các loại tiền tệ không xác định', () => {
// Arrange
const amount = 10;
// Act & Assert
// Chúng ta bọc lời gọi hàm trong một hàm mũi tên để toThrow của Jest hoạt động.
expect(() => {
CurrencyConverter.convert(amount, 'USD', 'XYZ');
}).toThrow('Unknown currency: XYZ');
});
Lưu tệp. Trình chạy kiểm thử ngay lập tức hiển thị một thất bại mới. Nó ĐỎ vì mã của chúng ta không ném ra lỗi; nó cố gắng truy cập `rates['USD']['XYZ']`, dẫn đến một `TypeError`. Bài kiểm thử mới của chúng ta đã xác định chính xác lỗ hổng này.
🟢 XANH: Làm cho bài kiểm thử mới vượt qua
Hãy sửa đổi `CurrencyConverter.js` để thêm xác thực.
// CurrencyConverter.js
const rates = {
USD: {
EUR: 0.92,
GBP: 0.80
},
EUR: {
USD: 1.08
}
};
const CurrencyConverter = {
convert(amount, from, to) {
if (!rates[from] || !rates[from][to]) {
// Xác định loại tiền nào không xác định để có thông báo lỗi tốt hơn
const unknownCurrency = !rates[from] ? from : to;
throw new Error(`Unknown currency: ${unknownCurrency}`);
}
return amount * rates[from][to];
}
};
module.exports = CurrencyConverter;
Lưu tệp. Cả hai bài kiểm thử bây giờ đều vượt qua. Chúng ta đã trở lại trạng thái XANH.
🔵 TÁI CẤU TRÚC: Dọn dẹp nó
Hàm `convert` của chúng ta đang phát triển. Logic xác thực đang bị trộn lẫn với tính toán. Chúng ta có thể trích xuất logic xác thực vào một hàm riêng tư để cải thiện khả năng đọc, nhưng hiện tại, nó vẫn có thể quản lý được. Điều quan trọng là chúng ta có quyền tự do thực hiện những thay đổi này vì các bài kiểm thử của chúng ta sẽ cho chúng ta biết nếu chúng ta làm hỏng bất cứ điều gì.
Vòng lặp 3: Tìm nạp tỷ giá bất đồng bộ
Việc mã hóa cứng tỷ giá là không thực tế. Hãy tái cấu trúc module của chúng ta để tìm nạp tỷ giá từ một API bên ngoài (được giả lập).
🔴 ĐỎ: Viết một bài kiểm thử bất đồng bộ giả lập một cuộc gọi API
Đầu tiên, chúng ta cần tái cấu trúc bộ chuyển đổi của mình. Bây giờ nó sẽ cần phải là một lớp mà chúng ta có thể khởi tạo, có lẽ với một client API. Chúng ta cũng sẽ cần phải giả lập API `fetch`. Jest làm cho điều này trở nên dễ dàng.
Hãy viết lại tệp kiểm thử của chúng ta để phù hợp với thực tế bất đồng bộ mới này. Chúng ta sẽ bắt đầu bằng cách kiểm thử lại trường hợp thành công.
// CurrencyConverter.test.js
const CurrencyConverter = require('./CurrencyConverter');
// Giả lập phụ thuộc bên ngoài
global.fetch = jest.fn();
beforeEach(() => {
// Xóa lịch sử giả lập trước mỗi bài kiểm thử
fetch.mockClear();
});
describe('CurrencyConverter', () => {
it('nên tìm nạp tỷ giá và chuyển đổi chính xác', async () => {
// Arrange
// Giả lập phản hồi API thành công
fetch.mockResolvedValueOnce({
json: () => Promise.resolve({ rates: { EUR: 0.92 } })
});
const converter = new CurrencyConverter('https://api.exchangerates.com');
const amount = 10; // 10 USD
// Act
const result = await converter.convert(amount, 'USD', 'EUR');
// Assert
expect(result).toBe(9.2);
expect(fetch).toHaveBeenCalledTimes(1);
expect(fetch).toHaveBeenCalledWith('https://api.exchangerates.com/latest?base=USD');
});
// Chúng ta cũng sẽ thêm các bài kiểm thử cho các lỗi API, v.v.
});
Chạy cái này sẽ dẫn đến một biển màu ĐỎ. `CurrencyConverter` cũ của chúng ta không phải là một lớp, không có phương thức `async`, và không sử dụng `fetch`.
🟢 XANH: Triển khai logic bất đồng bộ
Bây giờ, hãy viết lại `CurrencyConverter.js` để đáp ứng các yêu cầu của bài kiểm thử.
// CurrencyConverter.js
class CurrencyConverter {
constructor(apiUrl) {
this.apiUrl = apiUrl;
}
async convert(amount, from, to) {
const response = await fetch(`${this.apiUrl}/latest?base=${from}`);
if (!response.ok) {
throw new Error('Failed to fetch exchange rates.');
}
const data = await response.json();
const rate = data.rates[to];
if (!rate) {
throw new Error(`Unknown currency: ${to}`);
}
// Làm tròn đơn giản để tránh các vấn đề về số thập phân trong các bài kiểm thử
const convertedAmount = amount * rate;
return parseFloat(convertedAmount.toFixed(2));
}
}
module.exports = CurrencyConverter;
Khi bạn lưu, bài kiểm thử sẽ chuyển sang màu XANH. Lưu ý rằng chúng ta cũng đã thêm logic làm tròn để xử lý các sai số dấu phẩy động, một vấn đề phổ biến trong các tính toán tài chính.
🔵 TÁI CẤU TRÚC: Cải thiện mã bất đồng bộ
Phương thức `convert` đang làm rất nhiều việc: tìm nạp, xử lý lỗi, phân tích cú pháp và tính toán. Chúng ta có thể tái cấu trúc điều này bằng cách tạo một lớp `RateFetcher` riêng biệt chỉ chịu trách nhiệm giao tiếp API. `CurrencyConverter` của chúng ta sau đó sẽ sử dụng fetcher này. Điều này tuân theo Nguyên tắc Trách nhiệm Đơn lẻ và làm cho cả hai lớp dễ kiểm thử và bảo trì hơn. TDD hướng dẫn chúng ta đến thiết kế sạch sẽ hơn này.
Các Mẫu và Phản-Mẫu phổ biến trong TDD
Khi bạn thực hành TDD, bạn sẽ khám phá ra các mẫu hoạt động tốt và các phản-mẫu gây ra sự xích mích.
Các Mẫu tốt nên tuân theo
- Arrange, Act, Assert (AAA): Cấu trúc các bài kiểm thử của bạn thành ba phần rõ ràng. Sắp xếp (Arrange) thiết lập của bạn, Hành động (Act) bằng cách thực thi mã đang được kiểm thử, và Xác nhận (Assert) rằng kết quả là chính xác. Điều này làm cho các bài kiểm thử dễ đọc và dễ hiểu.
- Kiểm thử một hành vi tại một thời điểm: Mỗi trường hợp kiểm thử nên xác minh một hành vi duy nhất, cụ thể. Điều này làm cho rõ ràng những gì đã bị hỏng khi một bài kiểm thử thất bại.
- Sử dụng tên kiểm thử mang tính mô tả: Một tên kiểm thử như `it('nên ném ra lỗi nếu số tiền là âm')` có giá trị hơn nhiều so với `it('kiểm thử 1')`.
Các Phản-Mẫu cần tránh
- Kiểm thử chi tiết triển khai: Các bài kiểm thử nên tập trung vào API công khai ("cái gì"), chứ không phải là triển khai riêng tư ("cách thức"). Kiểm thử các phương thức riêng tư làm cho các bài kiểm thử của bạn trở nên giòn và khó tái cấu trúc.
- Bỏ qua bước Tái cấu trúc: Đây là sai lầm phổ biến nhất. Bỏ qua việc tái cấu trúc dẫn đến nợ kỹ thuật trong cả mã sản phẩm và bộ kiểm thử của bạn.
- Viết các bài kiểm thử lớn, chậm: Các bài kiểm thử đơn vị nên nhanh. Nếu chúng phụ thuộc vào cơ sở dữ liệu thực, các cuộc gọi mạng, hoặc hệ thống tệp, chúng sẽ trở nên chậm và không đáng tin cậy. Sử dụng mock và stub để cô lập các đơn vị của bạn.
TDD trong vòng đời phát triển rộng hơn
TDD không tồn tại trong chân không. Nó tích hợp tuyệt vời với các thực hành Agile và DevOps hiện đại, đặc biệt là cho các nhóm toàn cầu.
- TDD và Agile: Một user story hoặc một tiêu chí chấp nhận từ công cụ quản lý dự án của bạn có thể được chuyển đổi trực tiếp thành một loạt các bài kiểm thử thất bại. Điều này đảm bảo bạn đang xây dựng chính xác những gì doanh nghiệp yêu cầu.
- TDD và Tích hợp Liên tục/Triển khai Liên tục (CI/CD): TDD là nền tảng của một quy trình CI/CD đáng tin cậy. Mỗi khi một nhà phát triển đẩy mã, một hệ thống tự động (như GitHub Actions, GitLab CI, hoặc Jenkins) có thể chạy toàn bộ bộ kiểm thử. Nếu bất kỳ bài kiểm thử nào thất bại, bản dựng sẽ bị dừng lại, ngăn chặn lỗi đến tay người dùng. Điều này cung cấp phản hồi nhanh chóng, tự động cho toàn bộ nhóm, bất kể múi giờ.
- TDD vs. BDD (Phát triển hướng hành vi): BDD là một phần mở rộng của TDD tập trung vào sự hợp tác giữa các nhà phát triển, QA và các bên liên quan kinh doanh. Nó sử dụng một định dạng ngôn ngữ tự nhiên (Given-When-Then) để mô tả hành vi. Thông thường, một tệp tính năng BDD sẽ thúc đẩy việc tạo ra nhiều bài kiểm thử đơn vị theo phong cách TDD.
Kết luận: Hành trình của bạn với TDD
Phát triển Hướng Kiểm thử không chỉ là một chiến lược kiểm thử—đó là một sự thay đổi mô hình trong cách chúng ta tiếp cận phát triển phần mềm. Nó thúc đẩy một văn hóa về chất lượng, sự tự tin và hợp tác. Chu kỳ Đỏ-Xanh-Tái cấu trúc cung cấp một nhịp điệu ổn định hướng dẫn bạn đến mã sạch, mạnh mẽ và có thể bảo trì. Bộ kiểm thử kết quả trở thành một mạng lưới an toàn bảo vệ nhóm của bạn khỏi các lỗi hồi quy và tài liệu sống giúp các thành viên mới hòa nhập.
Đường cong học tập có thể cảm thấy dốc, và tốc độ ban đầu có thể có vẻ chậm hơn. Nhưng lợi ích lâu dài về thời gian gỡ lỗi giảm, thiết kế phần mềm được cải thiện và sự tự tin của nhà phát triển tăng lên là không thể đo đếm được. Hành trình để làm chủ TDD là một hành trình của kỷ luật và thực hành.
Hãy bắt đầu ngay hôm nay. Chọn một tính năng nhỏ, không quan trọng trong dự án tiếp theo của bạn và cam kết với quy trình. Viết bài kiểm thử trước. Xem nó thất bại. Làm cho nó vượt qua. Và sau đó, quan trọng nhất, tái cấu trúc. Trải nghiệm sự tự tin đến từ một bộ kiểm thử màu xanh, và bạn sẽ sớm tự hỏi làm thế nào bạn đã từng xây dựng phần mềm theo bất kỳ cách nào khác.